from django.http import HttpResponse,StreamingHttpResponse
from django.shortcuts import render
import json
import os
import requests
from contextlib import closing
from copy import deepcopy
from dwebsocket import require_websocket
import websocket
from threading import Thread
import gevent
try:
    import uwsgi
except:
    print('no uwsgi')

rtn_message = {
    "errorCode": 0,
    "errorMsg": ""
}

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
result_dir = os.path.join(BASE_DIR,'static')
# ================================================== ↓↓↓ 测试大文件上传转发 ↓↓↓ ========================================================
def get_h_html(request):
    print('+++++++++++ get +++++++++++++++')
    return render(request,'h.html')

def fileupload(request):
    rtn_msg = deepcopy(rtn_message)
    if request.method == 'POST':
        upload_file = request.FILES.get('file')
        task = request.POST.get('task_id')  # 获取文件唯一标识符
        chunk = request.POST.get('chunk', 0)  # 获取该分片在所有分片中的序号
        upload_url = 'http://127.0.0.1:8004/fileupload'
        data = {
            'task_id': task,
            'chunk': chunk,
        }
        files = {'file':(upload_file.name,upload_file)}
        response = requests.post(upload_url, data=data, files=files)
        if response.status_code == 200:
            result = json.loads(response.text)
            rtn_msg["data"] = result
        else:
            rtn_msg['errorCode'] = -1
            rtn_msg["errorMsg"] = '失败'
        return HttpResponse(json.dumps(rtn_msg))  
    else:    
        rtn_msg['errorCode'] = -1
        rtn_msg["errorMsg"] = '接口仅支持post'  
        return HttpResponse(json.dumps(rtn_msg))

def fileMerge(request):
    rtn_msg = deepcopy(rtn_message)
    upload_url = 'http://127.0.0.1:8004/fileMerge'
    if request.method == 'POST':
        task = request.POST.get('task_id')
        ext = request.POST.get('filename', '')
        upload_type = request.POST.get('type')
        uemail = request.POST.get('email')
        data = {
            'task_id': task,
            'filename': ext,
            'type': upload_type,
            'email': uemail,
        }
        response = requests.post(upload_url, data=data)
        if response.status_code == 200:
            result = json.loads(response.text)
            rtn_msg["data"] = result
        else:
            rtn_msg['errorCode'] = -1
            rtn_msg["errorMsg"] = '失败'
        return HttpResponse(json.dumps(rtn_msg))          
    else:    
        rtn_msg['errorCode'] = -1
        rtn_msg["errorMsg"] = '接口仅支持post'  
        return HttpResponse(json.dumps(rtn_msg))        

# ================================================== ↑↑↑ 测试大文件上传转发 ↑↑↑ ========================================================


# ================================================== ↓↓↓ 测试大文件下载转发 ↓↓↓ ========================================================
def fileDownload(request):
    if request.method == 'GET':
        return render(request,'fileDownload.html')

def get_hd_fname(request):
    if request.method == 'GET':
        return HttpResponse(json.dumps({'hd_fname':'action.mp4'}))

def getHDmovie(request):
    '''返回本地文件'''
    if request.method == 'GET':
        hd_fname = request.GET.get('hd_fname',None)
        if hd_fname:
            def file_iterator(file_name, chunk_size=512):
                with open(os.path.join(result_dir,file_name),'rb') as f:
                    while True:
                        c = f.read(chunk_size)
                        if c:
                            yield c
                        else:
                            break

            response = StreamingHttpResponse(file_iterator(hd_fname))
            response['Content-Type'] = 'application/octet-stream'
            response['Content-Disposition'] = 'attachment;filename="{0}"'.format(hd_fname)
            
            return response 
        else:
            return HttpResponse(json.dumps('文件不存在'))

def getRemoteHdMovie(request):
    hd_fname = request.GET.get('hd_fname',None)
    if hd_fname:
        def file_iterator(file_name, chunk_size=512):
            download_url = 'http://127.0.0.1:8004/getHDmovie'
            data = {
                'hd_fname': hd_fname
            }
            with closing(requests.get(url=download_url, params=data, stream=True)) as res:
                for chunk in res.iter_content(chunk_size=1024):
                    if chunk:
                        yield chunk
                    else:
                        break
        
        response = StreamingHttpResponse(file_iterator(hd_fname))
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="{0}"'.format(hd_fname)
        return response                        
    else:
        return HttpResponse(json.dumps({'err':'请携带hd_fname参数'}))
# ================================================== ↑↑↑ 测试大文件下载转发 ↑↑↑ ========================================================


# ================================================== ↓↓↓ 测试画风迁移的websocket转发 ↓↓↓ ========================================================
def upload(request):
    '''上传风格id或风格图片,以及内容图片, 进行风格迁移'''
    rtn_msg = deepcopy(rtn_message)
    upload_url = 'http://192.168.250.13:8002/style_migration'
    upload_data = {}
    f = request.FILES["content_img"]
    files = {'content_img':(f.name,f)}
    style_id = request.POST.get('style_id',None)
    color = request.POST.get('color',None)
    weight = request.POST.get('weight',None)
    if style_id:
        upload_data['style_id'] = style_id
    else:
        files['style_img'] = request.FILES['style_img']
    if color:
        upload_data['color'] = color
    if weight:
        upload_data['weight'] = weight
    response = requests.post(upload_url, data=upload_data, files=files)
    if response.status_code == 200:
        result = json.loads(response.text)
        rtn_msg["data"] = result
    else:
        rtn_msg['errorCode'] = -1
        rtn_msg["errorMsg"] = '失败'
    return HttpResponse(json.dumps(rtn_msg))

@require_websocket
def progress(request):
    rtn_msg = deepcopy(rtn_message)
    url = "ws://192.168.250.13:8002/progress"
    if not request.websocket:
        rtn_msg['errorCode'] = -1
        rtn_msg["errorMsg"] = "请以WEBSOCKET方式连接"
        return HttpResponse(json.dumps(rtn_msg))
    try:
        fname = request.websocket.wait()
        # 启用一个线程做websocket转发
        t = Thread(target=ws_worker,args=(url,request.websocket, fname))
        t.setDaemon(True)
        t.start()
        while t.is_alive():
            gevent.sleep(0.5)
        t.join()
        # return HttpResponse(json.dumps(rtn_msg))
    except Exception as e:
        print(e)
        rtn_msg['errorCode'] = -1
        rtn_msg["errorMsg"] = "WEBSOCKET错误"
        return HttpResponse(json.dumps(rtn_msg))  

def ws_worker(url,dws,fname):
    ws = WSClient(url, dws, fname)
    ws.test_websocket()

class WSClient():
    def __init__(self,url,dws,fname):
        self.dws = dws
        self.fname = fname
        self.ws = None
        self.url = url

    def test_websocket(self):
        def on_open(ws):
            ws.send(self.fname)

        def on_message(ws,message):
            self.dws.send(message)

        def on_error(ws, error):
            print(error)

        def on_close(ws):
            print("### closed ###")
            if self.ws:
                self.ws.close()

        websocket.enableTrace(True)
        self.ws = websocket.WebSocketApp(self.url,
                                    on_message=on_message,
                                    on_error=on_error,
                                    on_close=on_close)

        self.ws.on_open = on_open
        self.ws.run_forever()
# ================================================== ↑↑↑ 测试画风迁移的websocket转发 ↑↑↑ ========================================================

# ============================ 测试websocket部署 ======
def test_ws(request):
    while 1:
        print('waiting ws msg')
        try:
            msg = request.websocket.wait()
        except Exception as e:
            print('Websocket 连接断开: ',repr(e))
            break
        print('=========== type',type(msg),'content:',msg)
        if msg:
            msg = msg.decode()
            print('decoded msg: ',msg)
            request.websocket.send(json.dumps({'msg':'老王是'+msg}))
            # gevent.sleep(1)

def test_ws1(request):
    uwsgi.websocket_handshake()
    while 1:
        msg = uwsgi.websocket_recv()
        print('==== msg type: ',type(msg),'content: ',msg)
        if msg:
            msg = msg.decode()
            uwsgi.websocket_send(json.dumps({'msg':'老王是'+msg}))

def test_ws2(request):
    uwsgi.websocket_handshake()
    while 1:
        msg = uwsgi.websocket_recv()
        print('==== msg type: ',type(msg),'content: ',msg)
        if msg:
            msg = msg.decode()
            uwsgi.websocket_send(json.dumps({'msg':'老王2是'+msg}))            
